package com.lastproject.ejb.dao;

import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import com.lastproject.dto.BookDTO;
import com.lastproject.dto.ReviewContentDTO;
import com.lastproject.ejb.entities.Book;
import com.lastproject.ejb.entities.ReviewContent;
import com.lastproject.ejb.util.BookConversion;

@Stateless
public class ReviewContentDAO implements ReviewContentDAORemote {

	@PersistenceContext
	private EntityManager em;
	@EJB
	private BookConversion bookConvertor;

	public ReviewContentDAO() {
		super();
	}

	@Override
	public void createContent(ReviewContentDTO reviewContentDTO) {
		// check if there exists a review for a certain book
		Book foundBook = getBookById(reviewContentDTO.getBookId());
		ReviewContent reviewContent = getReviewContentByBook(foundBook);
		// update
		if (reviewContent != null) {
			reviewContent.setContent(reviewContentDTO.getContent());
			reviewContent.setBook(foundBook);
			em.persist(reviewContent);
		} else {
			// add new
			ReviewContent content = new ReviewContent();
			content.setContent(reviewContentDTO.getContent());
			content.setBook(foundBook);
			em.persist(content);
		}
	}

	private ReviewContent getReviewContentByBook(Book book) {
		TypedQuery<ReviewContent> query = em.createNamedQuery(
				"ReviewContent.findByBook", ReviewContent.class);
		query.setParameter("book", book);
		List<ReviewContent> resultList = query.getResultList();
		if (resultList != null && !resultList.isEmpty()) {
			return (ReviewContent) resultList.get(0);
		}
		return null;
	}

	/**
	 * Finds a book, given an ID.
	 * 
	 * @param id
	 *            the given ID.
	 * @return a book or null, otherwise.
	 */
	private Book getBookById(int id) {
		return em.find(Book.class, id);
	}

	@Override
	public BookDTO getById(int bookId) {
		Book foundBook = getBookById(bookId);
		return bookConvertor.fromEntity(foundBook);
	}

	@Override
	public byte[] getContent(BookDTO bookDTO) {
		Book book = bookConvertor.fromDTO(bookDTO);
		@SuppressWarnings("unchecked")
		List<byte[]> resultList = em
				.createNamedQuery("ReviewContent.findContent")
				.setParameter("book", book).getResultList();
		return resultList.get(0);
	}

	@Override
	public int hasContent(int bookId) {
		Query query = em.createNamedQuery("ReviewContent.hasCriticsReview");
		query.setParameter(1, bookId);
		@SuppressWarnings("rawtypes")
		List counts = query.getResultList();
		Long count = (Long) counts.get(0);
		return count.intValue();
	}

}
